昨天發現當一個函式回傳的物件類別是Future
時,無法將它assign至一個非Future的物件之中,使得目前資料庫中的內容無法成功顯示於應用程式之中。今日就來嘗試解決這個問題吧!
在做了一點資料查詢後,找到有人也有類似的疑問,以下為擷取StackOverflow問題:How to use a Future in a non-Future class的回答。
方法一:使用.then()
雖然這很容易,但筆者的程式中想要獲得value值也會遇到Future與non-Future類別的問題,因此這個方法應該不太容易實行
方法二:使用類別FutureBuilder
關於此類別的官方說明請點此
這是最多人推薦的方式,且下方有個好心人為原po寫了以下這個使用範例:
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'package:flutter/material.dart';
class UserModel {
final id;
final firstName;
UserModel({
this.firstName,
this.id,
});
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'],
firstName: json['firstName'],
);
}
}
Future<List<UserModel>?> decupagemJson() async {
var resposta = await rootBundle.loadString('assets/myData.json');
List dadosExtraidos = json.decode(resposta);
return dadosExtraidos.map((user) => UserModel.fromJson(user)).toList();
}
class YourClassName extends StatefulWidget {
@override
_YourClassNameState createState() => _YourClassNameState();
}
class _YourClassNameState extends State<YourClassName> {
late Future<List<UserModel>?> myList;
@override
void initState() {
myList = decupagemJson();
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
//to check if value returned from Future is correct
return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: Center(
child:
FutureBuilder<List<UserModel>?>(
builder: (con, snap) {
if (snap.hasData) {
return ListView.builder(
itemCount: snap.data!.length,
itemBuilder: (context, index) {
return Container(
color: Colors.red,
height: 90,
child: Column(
children: [
Text('id :${snap.data![index].id}'),
SizedBox(
height: 3,
),
Text('name :${snap.data![index].firstName}'),
SizedBox(
height: 10,
),
],
),
);
},
);
} else {
return CircularProgressIndicator();
}
},
future: myList,
),
),
);
}
}
接下來筆者將會嘗試將這個方法implement至自己的程式之中,中間需要一點時間try and error,因此最後的程式碼將會於之後再更新上來。